## -*- coding: utf-8 -*-
# # 文件
import os
# # 如果不保存在文件里 运行结果在运行结束后结果会被回收 如果需要持久化需要存储文件

# # _______________open参数_______________
# # file:  #文件的路径
# # mode:  #打开文件的模式  默认r(只读)
# # encoding  #打开的编码
# # 文件里使用open打开文件
# file1 = open('md/sss.txt', encoding='utf8', mode='r')
# print(type(file1))
# print(file1.read())
# file1.close()

# _______________路径_______________
# *****绝对路径*****
# H:\\gitee\\md\\文件.py
# windows 里 \ 分割符 (py里可以/ 也可以加r)
# unix类  里 / 分割符

# *****相对路径*****
# md/sss.txt
# 当前文件所在的文件夹路径
# 上一级../  ./可以省略不写(当前文件夹)
# /不能随便用

# _______________mode打开方式_______________
# mode='r' read  只读模式 (默认)  不存在报错
# mode='w' write 只能写入不能读取 不存在会新建文件
# file =open('yyy.txt','w') #新建yyy.txt
# mode='rb'       二进制读取模式
# mode='wb'       二进制写入模式 只能写二进制写
# mode='a' 文本末尾追加内容 不存在新建文件
# mode='r+'/'w+'  可读写 r+不存在会报错,w+会新建(用的少 需要重置光标 . seek(0,0))
# mode='w' write 只能写入不能读取 不存在会新建文件
# file = open('./md/sss.txt', 'r')
# # print(file.read())      #全文读取
# # print(file.readline())  #按行读取
# # print(file.readlines()) #把所有行的数据保存在一个列表里['www\n', 'hehe\n', 'haha \n', 'nihao \n', 'woshi no5\n', '66666\n', '7777\n', '呵呵\n', '坦克8']
# # x=file.read(2)          #读取2个长度,防止文件过大造成打开困难
# # print(x)                #没有绝对的优化除非提升硬件 软件优化时间或者空间

# file.close()


# _______________文件copy_______________
# file_name = input('请输入文件的路径')  # sss.txt--->sss.bak.txt
# if os.path.isfile(file_name):
#     # 打开旧文件
#     old_file = open(file_name,'rb') #以二进制打开可以避免错误 如果使用普通的打开对付图片无效


#     name=os.path.splitext(file_name)       #('./md/sss','.txt')
#     new_file_name= name[0]+'.bak'+name[1]

#     # name = (file_name.rpartition('.'))     #('./md/sss','.','txt')
#     # new_file_name= name[0]+'.bak.'+name[2]
#     new_file = open(new_file_name, 'wb')  #以二进制写入可以避免错误

#     # 对于大文件
#     # while True:
#     #     count=old_file.read(1024)
#     #     new_file.write(count)
#     #     if not count:
#     #         break

#     new_file.write(old_file.read())
#     new_file.close()
#     old_file.close()
# else:
#     print('文件不存在')


# _______________csv_______________
# 姓名,年纪,年级,城市
# 小王,18,6,深圳
# 王五,33,博一,乌海
# tom,22,大一,洛杉矶
# jack,12,初一,月球
# import csv
# file = open('demo.csv','w',encoding='utf8')
# w=csv.writer(file)

#___单行写入
# w.writerow(['name','age','score'])
# w.writerow(['小王',17,86])
# w.writerow(['小李',11,66])


#___多行写入
# w.writerows(
#     [
#         ['name','age','score'],
#         ['小李',11,66],
#         ['小李',11,66],
#         ['小李',11,66]
#     ]
# )

# #读取部分
# file=open('./md/sss.csv','r')
# f=csv.reader(file)
# for __each in f:
#     print(__each)
# file.close()

### __将数据写入内存(了解)__
# 涉及到 stringio 和 bytesio (二进制) 两个类
# from io import StringIO

# s_io =StringIO()
# # s_io.write('hello')  #内容写入内存进行缓存
# # s_io.write('good')

# # print(s_io.getvalue())

# # print('help',file=s_io)  #把文件打印到文件流存入内存里
# # print('hello',file=s_io)
# # print(s_io.getvalue())
# s_io.close()


#_____________sys模块的使用_____________
import sys #系统相关方法
# sys.exit(100)   #退出并打印退出码 100     hahaha

# print(sys.path)  #可以import 的文件存储位置  找不到报错
# sys.stdin        #接受标准的用户输入 和 input相关  可以不断输入 读取键盘⌨️
# sys.stdout       #接受标准的用户输出 修改可以改变默认输出位置
# sys.stderr       #改变默认的错误的输出位置


# s_in = sys.stdin
# while True:
#     content = s_in.readline().rstrip('\n')   #去掉换行
#     if content =='':#换行退出
#         break
#     print(content)

# sys.stdout=open('sswwws.txt','w',encoding='utf8')  #控制输出位置
# print('123')

#_____________序列号与反序列化_____________
# json与pickle
##______json
import json

# # 序列化就是将数据持久保存到磁盘或其他永久空间过程.  (不精确)
# # 反序列化就是把永久存储的的文件加载到内存         (不精确)

# file11=open ('name1.txt','w')
# # file.write('good')  #write只能写字符串或二进制
# name11=['ss','小名','ss']
# # file.write(name)  #write只能写字符串或二进制

# #将数据转为字符串
# # file.write(repr(name))  #少用
# # x=json.dumps(name,ensure_ascii=False)  #dumps(转为字符串)
# json.dump(name11,file11,ensure_ascii=False)      #转换为json字符串的同时写入指定文件
# # json '["张三","李四","王五"]'(字符串)
# # print(x)
# #转为二进制 pickle
# # file.write(x)

# # 持久化
# # json.dumps() 把字符串转为json字符串,不会保存到文件里   中文需要加 ensure_ascii=False
# # json.dump()  把字符串转为json字符串,并保存到指定文件里  中文需要加 ensure_ascii=False
# # 反序列化
# # json.loads() 把json字符串加载成python里的数据
# # json.load() 读取文件,把读取的内容加载成python里的数据
  
# file11.close()
# x='{"张三":"李四","王五":"1"}'
# p=json.loads(x)
# print(type(p))

# file1=open('name1.txt')
# y=json.load(file1)
# print(y)

# file1.close()
  
#______pickle  #二进制

# dumps(读取变量转为二进制)
# dump(转为二进制并保存文件) (name,file)
# loads(读取二进制并转为普通数据)
# load(文件里读取二进制并转为普通数据)(file)


# import pickle
# names=['张三','李四']
# b=pickle.dumps(names)
# # print(b)
# file=open('names.txt','wb')
# file.write(b)
# file.close()

# file1=open('names.txt','rb')
# x=file1.read()
# print(x)
# y=pickle.loads(x)
# print(y)
# file1.close()


#_____json与pickle的区别
# 神马情况下用json 神马情况下用pickle
# json()  只能保存部分信息,用来在不同的平台传递数据,只能是普通的数据类型
# pickle() 将数据原封不动的保存,加载回家继续用,只能在python里识别

# 如果需要转class 类的对象转成json
# class Person():
#     def __init__(self,name,age):
#         self.name=name
#         self.age=age
#     def eat(self):
#         print(self.name+'eat')


# p=Person('小王',16)

# print(json.dumps(p.__dict__,ensure_ascii=False))# 把对象转为字典, 
# 无法转eat等对象,只能加载self里的元素(不含动作)因为json字符串不认识对象

#_____________with 上下文管理器_____________
# with又叫上下文连接器,需要手动关闭的连接很多都能自动关闭(文件,scoket,数据库等)
# with关键词后面的对象需要实现 __enter__  __exit__ 方法 是上下文管理器
# 当进行到with代码块的时候,会自动调用__enter__方法
# 当离开with代码块的时候会自动调用__exit__方法

# try:
#     file=open('./md/ss1s.txt')
# except FileNotFoundError:
#     print('文件不存在')
# else:
#     try:
#         file.read()
#     finally:
#         file.close()
#_____等价于上面那个_____
try:
    with open('./md/s2ss.txt')as file:  #file调用__enter__方法  调用__exit__方法
        file.read()                     #file在read以前是None
except FileNotFoundError:
    print('文件没有找到')
    





